<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<script src="../resources/js-test.js"></script>
</head>
<body>
<div id="description"></div>
<div id="console"></div>

<script>

description("This test exercises the CSSMatrix 3D interface");

debug("");
debug("CSSMatrix constructors");

var m = null;
m = new WebKitCSSMatrix();
if (m)
  testPassed("default constructor");
else
  testFailed("default constructor");

var m2 = new WebKitCSSMatrix(m);
if (m2)
  testPassed("object constructor");
else
  testFailed("object constructor");

m = new WebKitCSSMatrix("matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1)");
if (m)
  testPassed("string constructor");
else
  testFailed("string constructor");

debug("");
debug("Test toString");
var m = new WebKitCSSMatrix("matrix3d(1, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1)");
var s = m.toString();
var a = s.split('(');
shouldBe('a[0]', '"matrix3d"');
var a2 = a[1].split(',');
shouldBe('parseFloat(a2[0])', '1');
shouldBe('parseFloat(a2[1])', '0');
shouldBe('parseFloat(a2[2])', '0');
shouldBe('parseFloat(a2[3])', '1');
shouldBe('parseFloat(a2[4])', '0');
shouldBe('parseFloat(a2[5])', '1');
shouldBe('parseFloat(a2[6])', '0');
shouldBe('parseFloat(a2[7])', '0');
shouldBe('parseFloat(a2[8])', '0');
shouldBe('parseFloat(a2[9])', '0');
shouldBe('parseFloat(a2[10])', '1');
shouldBe('parseFloat(a2[11])', '0');
shouldBe('parseFloat(a2[12])', '0');
shouldBe('parseFloat(a2[13])', '0');
shouldBe('parseFloat(a2[14])', '0');
var a3 = a2[15].split(")");
shouldBe('parseFloat(a3[0])', '1');
shouldBe('a3[1]', '""');

debug("");
debug("Test bad input to string constructor");
shouldThrow('new WebKitCSSMatrix("banana")');

debug("");
debug("Test attributes on default matrix");
m = new WebKitCSSMatrix();
shouldBe('m.m11', '1');
shouldBe('m.m12', '0');
shouldBe('m.m13', '0');
shouldBe('m.m14', '0');
shouldBe('m.m21', '0');
shouldBe('m.m22', '1');
shouldBe('m.m23', '0');
shouldBe('m.m24', '0');
shouldBe('m.m31', '0');
shouldBe('m.m32', '0');
shouldBe('m.m33', '1');
shouldBe('m.m34', '0');
shouldBe('m.m41', '0');
shouldBe('m.m42', '0');
shouldBe('m.m43', '0');
shouldBe('m.m44', '1');

debug("");
debug("Test attributes on custom matrix");
m = new WebKitCSSMatrix("matrix3d(11, 12, 13, 14, 21, 22, 23, 24, 31, 32, 33, 34, 41, 42, 43, 44)");
shouldBe('m.m11', '11');
shouldBe('m.m12', '12');
shouldBe('m.m13', '13');
shouldBe('m.m14', '14');
shouldBe('m.m21', '21');
shouldBe('m.m22', '22');
shouldBe('m.m23', '23');
shouldBe('m.m24', '24');
shouldBe('m.m31', '31');
shouldBe('m.m32', '32');
shouldBe('m.m33', '33');
shouldBe('m.m34', '34');
shouldBe('m.m41', '41');
shouldBe('m.m42', '42');
shouldBe('m.m43', '43');
shouldBe('m.m44', '44');

debug("");
debug("Test setMatrixValue - set to matrix()");
m = new WebKitCSSMatrix();
m.setMatrixValue("matrix3d(11, 12, 13, 14, 21, 22, 23, 24, 31, 32, 33, 34, 41, 42, 43, 44)");
shouldBe('m.m11', '11');
shouldBe('m.m12', '12');
shouldBe('m.m13', '13');
shouldBe('m.m14', '14');
shouldBe('m.m21', '21');
shouldBe('m.m22', '22');
shouldBe('m.m23', '23');
shouldBe('m.m24', '24');
shouldBe('m.m31', '31');
shouldBe('m.m32', '32');
shouldBe('m.m33', '33');
shouldBe('m.m34', '34');
shouldBe('m.m41', '41');
shouldBe('m.m42', '42');
shouldBe('m.m43', '43');
shouldBe('m.m44', '44');

debug("");
debug("Test setMatrixValue - set to translate(10px, 20px, 30px) scale(2, 3, 4)");
m = new WebKitCSSMatrix();
m.setMatrixValue("translate3d(10px, 20px, 30px) scale3d(2, 3, 4)");
shouldBe('m.m11', '2');
shouldBe('m.m12', '0');
shouldBe('m.m13', '0');
shouldBe('m.m14', '0');
shouldBe('m.m21', '0');
shouldBe('m.m22', '3');
shouldBe('m.m23', '0');
shouldBe('m.m24', '0');
shouldBe('m.m31', '0');
shouldBe('m.m32', '0');
shouldBe('m.m33', '4');
shouldBe('m.m34', '0');
shouldBe('m.m41', '10');
shouldBe('m.m42', '20');
shouldBe('m.m43', '30');
shouldBe('m.m44', '1');

debug("");
debug("Test throwing exception from setMatrixValue");
shouldThrow('m.setMatrixValue("banana")');
shouldThrow('m.setMatrixValue("translate3d(10em, 20%, 40)")');
shouldThrow('m.setMatrixValue("translate3d(10px, 20px, 30px) scale3d()")');

debug("");
debug("Test multiply");
m =  new WebKitCSSMatrix("matrix3d( 1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15, 16)");
m2 = new WebKitCSSMatrix("matrix3d(17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32)");
var m3 = m.multiply(m2);
shouldBe('parseFloat(m3.m11)', '538');
shouldBe('parseFloat(m3.m12)', '612');
shouldBe('parseFloat(m3.m13)', '686');
shouldBe('parseFloat(m3.m14)', '760');
shouldBe('parseFloat(m3.m21)', '650');
shouldBe('parseFloat(m3.m22)', '740');
shouldBe('parseFloat(m3.m23)', '830');
shouldBe('parseFloat(m3.m24)', '920');
shouldBe('parseFloat(m3.m31)', '762');
shouldBe('parseFloat(m3.m32)', '868');
shouldBe('parseFloat(m3.m33)', '974');
shouldBe('parseFloat(m3.m34)', '1080');
shouldBe('parseFloat(m3.m41)', '874');
shouldBe('parseFloat(m3.m42)', '996');
shouldBe('parseFloat(m3.m43)', '1118');
shouldBe('parseFloat(m3.m44)', '1240');

debug("");
debug("Test immutability of multiply");
shouldBe('parseFloat(m.m11)', '1');
shouldBe('parseFloat(m.m12)', '2');
shouldBe('parseFloat(m.m13)', '3');
shouldBe('parseFloat(m.m14)', '4');
shouldBe('parseFloat(m.m21)', '5');
shouldBe('parseFloat(m.m22)', '6');
shouldBe('parseFloat(m.m23)', '7');
shouldBe('parseFloat(m.m24)', '8');
shouldBe('parseFloat(m.m31)', '9');
shouldBe('parseFloat(m.m32)', '10');
shouldBe('parseFloat(m.m33)', '11');
shouldBe('parseFloat(m.m34)', '12');
shouldBe('parseFloat(m.m41)', '13');
shouldBe('parseFloat(m.m42)', '14');
shouldBe('parseFloat(m.m43)', '15');
shouldBe('parseFloat(m.m44)', '16');

debug("");
debug("Test multiply in an affine matrix");
m =  new WebKitCSSMatrix("matrix3d(1, 2, 0, 0, 3, 4, 0, 0, 0, 0, 1, 0, 5, 6, 0, 1)");
m2 = new WebKitCSSMatrix("matrix3d(7, 8, 0, 0, 9, 10, 0, 0, 0, 0, 1, 0, 11, 12, 0, 1)");
var m3 = m.multiply(m2);
shouldBe('parseFloat(m3.m11)', '31');
shouldBe('parseFloat(m3.m12)', '46');
shouldBe('parseFloat(m3.m13)', '0');
shouldBe('parseFloat(m3.m14)', '0');
shouldBe('parseFloat(m3.m21)', '39');
shouldBe('parseFloat(m3.m22)', '58');
shouldBe('parseFloat(m3.m23)', '0');
shouldBe('parseFloat(m3.m24)', '0');
shouldBe('parseFloat(m3.m31)', '0');
shouldBe('parseFloat(m3.m32)', '0');
shouldBe('parseFloat(m3.m33)', '1');
shouldBe('parseFloat(m3.m34)', '0');
shouldBe('parseFloat(m3.m41)', '52');
shouldBe('parseFloat(m3.m42)', '76');
shouldBe('parseFloat(m3.m43)', '0');
shouldBe('parseFloat(m3.m44)', '1');

debug("");
debug("Test that multiply works in the right direction");
var tx = new WebKitCSSMatrix("matrix3d( 1,  0,  0,  0,  0,  1,  0,  0,  0, 0, 1, 0, 100, 0, 0, 1)");
var sx = new WebKitCSSMatrix("matrix3d( 2,  0,  0,  0,  0,  1,  0,  0,  0, 0, 1, 0, 0, 0, 0, 1)");
m = tx.multiply(sx);
shouldBe('m.m11', '2');
shouldBe('m.m12', '0');
shouldBe('m.m13', '0');
shouldBe('m.m14', '0');
shouldBe('m.m21', '0');
shouldBe('m.m22', '1');
shouldBe('m.m23', '0');
shouldBe('m.m24', '0');
shouldBe('m.m31', '0');
shouldBe('m.m32', '0');
shouldBe('m.m33', '1');
shouldBe('m.m34', '0');
shouldBe('m.m41', '100');
shouldBe('m.m42', '0');
shouldBe('m.m43', '0');
shouldBe('m.m44', '1');

debug("");
debug("Test inverse");
m = new WebKitCSSMatrix("matrix3d(2, 0, 0, 0, 0, 2, 0, 0, 0, 0, 2, 0, 10, 20, 30, 1)");
m2 = m.inverse();

shouldBe('parseFloat(m2.m11)', '0.5');
shouldBe('parseFloat(m2.m12)', '0');
shouldBe('parseFloat(m2.m13)', '0');
shouldBe('parseFloat(m2.m14)', '0');
shouldBe('parseFloat(m2.m21)', '0');
shouldBe('parseFloat(m2.m22)', '0.5');
shouldBe('parseFloat(m2.m23)', '0');
shouldBe('parseFloat(m2.m24)', '0');
shouldBe('parseFloat(m2.m31)', '0');
shouldBe('parseFloat(m2.m32)', '0');
shouldBe('parseFloat(m2.m33)', '0.5');
shouldBe('parseFloat(m2.m34)', '0');
shouldBe('parseFloat(m2.m41)', '-5');
shouldBe('parseFloat(m2.m42)', '-10');
shouldBe('parseFloat(m2.m43)', '-15');
shouldBe('parseFloat(m2.m44)', '1');

debug("");
debug("Test immutability of inverse");
shouldBe('parseFloat(m.m11)', '2');
shouldBe('parseFloat(m.m12)', '0');
shouldBe('parseFloat(m.m13)', '0');
shouldBe('parseFloat(m.m14)', '0');
shouldBe('parseFloat(m.m21)', '0');
shouldBe('parseFloat(m.m22)', '2');
shouldBe('parseFloat(m.m23)', '0');
shouldBe('parseFloat(m.m24)', '0');
shouldBe('parseFloat(m.m31)', '0');
shouldBe('parseFloat(m.m32)', '0');
shouldBe('parseFloat(m.m33)', '2');
shouldBe('parseFloat(m.m34)', '0');
shouldBe('parseFloat(m.m41)', '10');
shouldBe('parseFloat(m.m42)', '20');
shouldBe('parseFloat(m.m43)', '30');
shouldBe('parseFloat(m.m44)', '1');

debug("");
debug("Test not invertible 3d matrix");
m = new WebKitCSSMatrix("matrix3d(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)"); // not invertible
m2 = m.inverse();

shouldBeNaN('m2.m11');
shouldBeNaN('m2.m12');
shouldBeNaN('m2.m13');
shouldBeNaN('m2.m14');
shouldBeNaN('m2.m21');
shouldBeNaN('m2.m22');
shouldBeNaN('m2.m23');
shouldBeNaN('m2.m24');
shouldBeNaN('m2.m31');
shouldBeNaN('m2.m32');
shouldBeNaN('m2.m33');
shouldBeNaN('m2.m34');
shouldBeNaN('m2.m41');
shouldBeNaN('m2.m42');
shouldBeNaN('m2.m43');
shouldBeNaN('m2.m44');

debug("");
debug("Test immutability of inverse");
shouldBe('m.m11', '0');
shouldBe('m.m12', '0');
shouldBe('m.m13', '0');
shouldBe('m.m14', '0');
shouldBe('m.m21', '0');
shouldBe('m.m22', '0');
shouldBe('m.m23', '0');
shouldBe('m.m24', '0');
shouldBe('m.m31', '0');
shouldBe('m.m32', '0');
shouldBe('m.m33', '0');
shouldBe('m.m34', '0');
shouldBe('m.m41', '0');
shouldBe('m.m42', '0');
shouldBe('m.m43', '0');
shouldBe('m.m44', '0');

debug("");
debug("Test translate");
m = new WebKitCSSMatrix();
var m2 = m.translate(10, 20, 30);
shouldBe('m2.m11', '1');
shouldBe('m2.m12', '0');
shouldBe('m2.m13', '0');
shouldBe('m2.m14', '0');
shouldBe('m2.m21', '0');
shouldBe('m2.m22', '1');
shouldBe('m2.m23', '0');
shouldBe('m2.m24', '0');
shouldBe('m2.m31', '0');
shouldBe('m2.m32', '0');
shouldBe('m2.m33', '1');
shouldBe('m2.m34', '0');
shouldBe('m2.m41', '10');
shouldBe('m2.m42', '20');
shouldBe('m2.m43', '30');
shouldBe('m2.m44', '1');

debug("");
debug("Test immutability of translate");
shouldBe('m.m11', '1');
shouldBe('m.m12', '0');
shouldBe('m.m13', '0');
shouldBe('m.m14', '0');
shouldBe('m.m21', '0');
shouldBe('m.m22', '1');
shouldBe('m.m23', '0');
shouldBe('m.m24', '0');
shouldBe('m.m31', '0');
shouldBe('m.m32', '0');
shouldBe('m.m33', '1');
shouldBe('m.m34', '0');
shouldBe('m.m41', '0');
shouldBe('m.m42', '0');
shouldBe('m.m43', '0');
shouldBe('m.m44', '1');

debug("");
debug("Test scale");
m = new WebKitCSSMatrix();
m2 = m.scale(10, 20, 30);
shouldBe('m2.m11', '10');
shouldBe('m2.m12', '0');
shouldBe('m2.m13', '0');
shouldBe('m2.m14', '0');
shouldBe('m2.m21', '0');
shouldBe('m2.m22', '20');
shouldBe('m2.m23', '0');
shouldBe('m2.m24', '0');
shouldBe('m2.m31', '0');
shouldBe('m2.m32', '0');
shouldBe('m2.m33', '30');
shouldBe('m2.m34', '0');
shouldBe('m2.m41', '0');
shouldBe('m2.m42', '0');
shouldBe('m2.m43', '0');
shouldBe('m2.m44', '1');

debug("");
debug("Test immutability of scale");
shouldBe('m.m11', '1');
shouldBe('m.m12', '0');
shouldBe('m.m13', '0');
shouldBe('m.m14', '0');
shouldBe('m.m21', '0');
shouldBe('m.m22', '1');
shouldBe('m.m23', '0');
shouldBe('m.m24', '0');
shouldBe('m.m31', '0');
shouldBe('m.m32', '0');
shouldBe('m.m33', '1');
shouldBe('m.m34', '0');
shouldBe('m.m41', '0');
shouldBe('m.m42', '0');
shouldBe('m.m43', '0');
shouldBe('m.m44', '1');

debug("");
debug("Test rotate");
m = new WebKitCSSMatrix();
m2 = m.rotate(10, 20, 30);
shouldBe('parseFloat(m2.m11.toPrecision(6))', '0.813798');
shouldBe('parseFloat(m2.m12.toPrecision(6))', '0.469846');
shouldBe('parseFloat(m2.m13.toPrecision(6))', '-0.34202');
shouldBe('parseFloat(m2.m14.toPrecision(6))', '0');
shouldBe('parseFloat(m2.m21.toPrecision(6))', '-0.44097');
shouldBe('parseFloat(m2.m22.toPrecision(6))', '0.882564');
shouldBe('parseFloat(m2.m23.toPrecision(6))', '0.163176');
shouldBe('parseFloat(m2.m24.toPrecision(6))', '0');
shouldBe('parseFloat(m2.m31.toPrecision(6))', '0.378522');
shouldBe('parseFloat(m2.m32.toPrecision(6))', '0.0180283');
shouldBe('parseFloat(m2.m33.toPrecision(6))', '0.925417');
shouldBe('parseFloat(m2.m34.toPrecision(6))', '0');
shouldBe('parseFloat(m2.m41.toPrecision(6))', '0');
shouldBe('parseFloat(m2.m42.toPrecision(6))', '0');
shouldBe('parseFloat(m2.m43.toPrecision(6))', '0');
shouldBe('parseFloat(m2.m44.toPrecision(6))', '1');

debug("");
debug("Test immutability of rotate");
shouldBe('m.m11', '1');
shouldBe('m.m12', '0');
shouldBe('m.m13', '0');
shouldBe('m.m14', '0');
shouldBe('m.m21', '0');
shouldBe('m.m22', '1');
shouldBe('m.m23', '0');
shouldBe('m.m24', '0');
shouldBe('m.m31', '0');
shouldBe('m.m32', '0');
shouldBe('m.m33', '1');
shouldBe('m.m34', '0');
shouldBe('m.m41', '0');
shouldBe('m.m42', '0');
shouldBe('m.m43', '0');
shouldBe('m.m44', '1');

debug("");
debug("Test rotateAxisAngle");
m = new WebKitCSSMatrix();
m2 = m.rotateAxisAngle(0.707, 0.707, 0.707, 45);
shouldBe('parseFloat(m2.m11.toPrecision(6))', '0.804738');
shouldBe('parseFloat(m2.m12.toPrecision(6))', '0.505879');
shouldBe('parseFloat(m2.m13.toPrecision(6))', '-0.310617');
shouldBe('parseFloat(m2.m14.toPrecision(6))', '0');
shouldBe('parseFloat(m2.m21.toPrecision(6))', '-0.310617');
shouldBe('parseFloat(m2.m22.toPrecision(6))', '0.804738');
shouldBe('parseFloat(m2.m23.toPrecision(6))', '0.505879');
shouldBe('parseFloat(m2.m24.toPrecision(6))', '0');
shouldBe('parseFloat(m2.m31.toPrecision(6))', '0.505879');
shouldBe('parseFloat(m2.m32.toPrecision(6))', '-0.310617');
shouldBe('parseFloat(m2.m33.toPrecision(6))', '0.804738');
shouldBe('parseFloat(m2.m34.toPrecision(6))', '0');
shouldBe('parseFloat(m2.m41.toPrecision(6))', '0');
shouldBe('parseFloat(m2.m42.toPrecision(6))', '0');
shouldBe('parseFloat(m2.m43.toPrecision(6))', '0');
shouldBe('parseFloat(m2.m44.toPrecision(6))', '1');

debug("");
debug("Test immutability of rotateAxisAngle");
shouldBe('m.m11', '1');
shouldBe('m.m12', '0');
shouldBe('m.m13', '0');
shouldBe('m.m14', '0');
shouldBe('m.m21', '0');
shouldBe('m.m22', '1');
shouldBe('m.m23', '0');
shouldBe('m.m24', '0');
shouldBe('m.m31', '0');
shouldBe('m.m32', '0');
shouldBe('m.m33', '1');
shouldBe('m.m34', '0');
shouldBe('m.m41', '0');
shouldBe('m.m42', '0');
shouldBe('m.m43', '0');
shouldBe('m.m44', '1');

debug("");

</script>

<script>
</script>

</body>
</html>
